﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CashCommon;
using System.ComponentModel;
using System.Diagnostics;
using CashResource;
using System.Windows.Forms;

namespace Cash.Model
{
    public interface ICashAccountGate
    {
        void RemoveCashAccount(int[] cashAccountId);
        bool CashAccountExist(int activeUserId, int cashAccountId);
        CashAccount ApplyToDb(CashAccount cashAccount);
        void RefreshFromDb(CashAccount cashAccount);
        Sequence GetSequence(SqlSwitch swth);
    }

    public class CashAccount : IDataErrorInfo
    {
        #region Создание кассового счета

        /// <summary>
        /// Статический метод класса для создания нового счета в системе
        /// </summary>
        public static CashAccount Instant()
        {
            return new CashAccount();
        }

        /// <summary>
        /// По переданному идентификатору, создается экземпляр класса.
        /// </summary>
        /// <param name="userId">Идентификатор счета в базе данных</param>
        /// <returns>Возвращается экземпляр класса счета. Если счет с заданным ID  не найден, возвращается null</returns>
        public static CashAccount Instant(int userId)
        {
            return new CashAccount(userId);
        }
        
        /// <summary>
        /// Защищенный конструктор для создания "пустого" счета
        /// </summary>
        protected CashAccount() { }

        /// <summary>
        /// Защищенный конструктор для создания счета, и инициалзизации его полей из базы данных
        /// </summary>
        protected CashAccount(int id) 
        {
            this.LINK = id;
            RefreshFromDb();
        }

        #endregion

        #region Методы счета

        /// <summary>
        /// Удаление одного или нескольких счетов по их идентификатору (LINK)
        /// </summary>
        /// <param name="ids"></param>
        public static void RemoveById(int[] ids)
        {
            _gate.RemoveCashAccount(ids);
        }
        public void SetStatePaied(DateTime dtPaied)
        {
            return;
        }
        public static void OpenSequence(DataGridView dataGrid, SqlSwitch sqlSwitch, List<string> fieldsVisible, OrderBy orderBy)
        {
            Sequence sqc = Builder.CashAccountGate.GetSequence(null);
            if (sqlSwitch != null)
                sqc.SqlSwitch = sqlSwitch;
             sqc.OrderBy = orderBy;
            sqc.PrimaryKey.Add("LINK");
            sqc.DGV = dataGrid;
            sqc.Open();
            if (fieldsVisible != null)
                sqc.SetVisibleFields(fieldsVisible);
        }

        #endregion

        #region Свойства счета

        /// <summary>
        /// Идентификатор счета из базы данных
        /// </summary>
        public int LINK { get; private set; }
        /// <summary>
        /// Номер счета
        /// </summary>
        public string Number { get; set; }
        /// <summary>
        /// Наименование абонента
        /// </summary>
        public string AbonentName { get; set; }
        /// <summary>
        /// Идентификатор пользователя
        /// </summary>
        public int F_Subscr { get; set; }
        /// <summary>
        /// Наименование подразделения
        /// </summary>
        public string DepartmentName { get; set; }
        /// <summary>
        /// Дата печати 
        /// </summary>
        public DateTime DatePrint { get; set; }
        /// <summary>
        /// Количество денег
        /// </summary>
        public double Amount { get; set; }
        /// <summary>
        /// Ставка НДС
        /// </summary>
        public int N_Tax { get; set; }
        /// <summary>
        /// Статья реализации
        /// </summary>
        public string Sale_Categories_Name { get; set; }
        /// <summary>
        /// Идентификатор вида энергии
        /// </summary>
        public int F_Sale_Categories { get; set; }
        /// <summary>
        /// Статья реализации
        /// </summary>
        public string Sale_Items_Name { get; set; }
        /// <summary>
        /// Идентификатор статьи реалзации
        /// </summary>
        public int F_Sale_Items { get; set; }
        /// <summary>
        /// Основание
        /// </summary>
        public string C_Foundation { get; set; }
        /// <summary>
        /// Идентификатор подразделения
        /// </summary>
        public int F_Division { get; set; }
        /// <summary>
        /// Номер договора
        /// </summary>
        public string C_Order_Number { get; set; }
        /// <summary>
        /// Если счет является счетом реализации = 1, если нет 0
        /// </summary>
        public int N_Releaze { get; set; }

        #endregion

        #region Helper

        /// <summary>
        /// Значения полей счета обновляются значениями из базы данных
        /// </summary>
        public void RefreshFromDb()
        {
            _gate.RefreshFromDb(this);
        }

        /// <summary>
        /// Новые значения полей счета сохраняются в базе данных
        /// </summary>
        public void ApplyToDb()
        {
            _gate.ApplyToDb(this);
        }

        #endregion

        #region Реализация IDataErrorInfo
        
        public string Error
        {
            get { return null; }
        }

        public string this[string propertyName]
        {
            get { return this.GetValidationError(propertyName); }
        }

        /// <summary>
        /// Свойства класса, для которых отрабатывается правильность введеннх данных
        /// </summary>
        private readonly string[] ValidatedProperties = 
        { 
            "LINK" 
        };

        private string GetValidationError(string propertyName)
        {
            if (Array.IndexOf(ValidatedProperties, propertyName) < 0)
                return null;

            string error = null;

            switch (propertyName)
            {
                case "ID":
                    error = this.ValidateID();
                    break;
                default:
                    Debug.Fail("Unexpected property being validated on Customer: " + propertyName);
                    break;
            }

            return error;
        }

        /// <summary>
        /// Проверяет валидность всего объекта, обрабатывая состояние всех свойств
        /// </summary>
        public bool IsValid
        {
            get 
            {
                foreach (string property in ValidatedProperties)
                    if (GetValidationError(property) != null)
                        return false;

                return true;
            }
        }
        private string ValidateID()
        {
            if (this.LINK < 0)
            {
                return CommonError.CashAccountValidID;
            }
            return null;
        }

        #endregion

        #region Fields
        
        private static ICashAccountGate _gate = Builder.CashAccountGate;
        
        #endregion
    }

}
